<?php
namespace app\index\controller;

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Core\OssUtil;
use think\Config;
use think\Controller;
use think\Env;

class Index extends Controller
{
    // 阿里OSS相关参数
    protected $accessKeyId = '';
    protected $accessKeySecret = '';
    protected $endpoint = '';
    protected $bucket = '';
    // 文件上传相关设置
    protected $image_size = 0;
    protected $video_size = 0;
    protected $other_size = 0;

    /**
     * 构造函数
     */
    public function _initialize()
    {
        $this->accessKeyId = Env::get('aliyun_oss')['accessKeyId'];
        $this->accessKeySecret = Env::get('aliyun_oss')['accessKeySecret'];
        $this->endpoint = Env::get('aliyun_oss')['endpoint'];
        $this->bucket = Env::get('aliyun_oss')['bucket'];
        $this->image_size = Env::get('upload_set')['image_size'];
        $this->video_size = Env::get('upload_set')['video_size'];
        $this->other_size = Env::get('upload_set')['other_size'];
    }

    /**
     * 测试页面
     */
    public function index()
    {
        return $this->fetch();
    }

    /**
     * 创建存储空间
     */
    public function createBucket()
    {
        if (!request()->isPost()) {
            throw new \think\Exception('请求方式错误！');
        }
        $bucket = input('param.bucket');
        if (empty($bucket)) {
            return json(['data' => '', 'code' => 1, 'message' => '存储空间名不能为空！']);
        }
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $ossClient->createBucket($bucket);
            return json(['data' => '', 'code' => 0, 'message' => $bucket . '存储空间创建成功']);
        } catch (OssException $e) {
            return json(['data' => $e->getMessage(), 'code' => 1, 'message' => '创建失败']);
        }
    }

    /**
     * 上传文件
     */
    public function uploadFile()
    {
        /*判断提交方式*/
        if (!request()->isPost()) {
            throw new \think\Exception('请求方式错误！');
        }
        /*获取到上传的文件*/
        $file = $_FILES['file'];
        if (!$file) {
            return json(['data' => '', 'code' => 1, 'message' => '文件不存在！']);
        }
        // 判断文件大小
        if ($file['size'] > $this->other_size) {
            return json(['data' => '', 'code' => 1, 'message' => '文件大小不能超过' . ($this->other_size / 1024 / 1024) . 'M']);
        }
        $name = $file['name'];
        $format = strrchr($name, '.');//截取文件后缀名如 (.jpg)
        /*判断图片格式*/
        $allow_type = ['.zip', '.rar', '.doc', '.docx', 'xls', 'xlsx', 'mp3', 'wav'];
        if (!in_array($format, $allow_type)) {
            return json(['data' => '', 'code' => 1, 'message' => '文件格式不在允许范围内']);
        }
        // 尝试执行
        try {
            //实例化对象 将配置传入
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            //这里是有sha1加密 生成文件名 之后连接上后缀
            $fileName = 'upload/file/' . date("Ymd") . '/' . sha1(date('YmdHis', time()) . uniqid()) . $format;
            //执行阿里云上传
            $result = $ossClient->uploadFile($this->bucket, $fileName, $file['tmp_name']);
            /*组合返回数据*/
            $arr = [
                'oss_url' => $result['info']['url'],  //上传资源地址
                'relative_path' => $fileName     //数据库保存名称(相对路径)
            ];
        } catch (OssException $e) {
            return json(['data' => $e->getMessage(), 'code' => 1, 'message' => '上传失败！']);
        }
        //将结果返回
        return json(['data' => array('file' => $arr['oss_url']), 'code' => 0, 'message' => '成功上传到oss']);
    }

    /**
     * 上传视频
     */
    public function uploadVideo()
    {
        /*判断提交方式*/
        if (!request()->isPost()) {
            throw new \think\Exception('请求方式错误！');
        }
        /*获取到上传的文件*/
        $file = $_FILES['file'];
        if (!$file) {
            return json(['data' => '', 'code' => 1, 'message' => '文件不存在！']);
        }
        // 判断文件大小
        if ($file['size'] > $this->video_size) {
            return json(['data' => '', 'code' => 1, 'message' => '视频大小不能超过' . ($this->video_size / 1024 / 1024) . 'M']);
        }
        $name = $file['name'];
        $format = strrchr($name, '.');//截取文件后缀名如 (.jpg)
        /*判断图片格式*/
        $allow_type = ['.mp4', '.avi', '.rmvb'];
        if (!in_array($format, $allow_type)) {
            return json(['data' => '', 'code' => 1, 'message' => '视频格式不在允许范围内']);
        }
        // 尝试执行
        try {
            //实例化对象 将配置传入
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            //这里是有sha1加密 生成文件名 之后连接上后缀
            $fileName = 'upload/video/' . date("Ymd") . '/' . sha1(date('YmdHis', time()) . uniqid()) . $format;
            //执行阿里云上传
            $result = $ossClient->uploadFile($this->bucket, $fileName, $file['tmp_name']);
            /*组合返回数据*/
            $arr = [
                'oss_url' => $result['info']['url'],  //上传资源地址
                'relative_path' => $fileName     //数据库保存名称(相对路径)
            ];
        } catch (OssException $e) {
            return json(['data' => $e->getMessage(), 'code' => 1, 'message' => '上传失败！']);
        }
        //将结果返回
        return json(['data' => array('file' => $arr['oss_url']), 'code' => 0, 'message' => '成功上传到oss']);
    }

    /**
     * 上传图片
     */
    public function uploadImage()
    {
        /*判断提交方式*/
        if (!request()->isPost()) {
            throw new \think\Exception('请求方式错误！');
        }
        /*获取到上传的文件*/
        $file = $_FILES['file'];
        if (!$file) {
            return json(['data' => '', 'code' => 1, 'message' => '文件不存在！']);
        }
        // 判断文件大小
        if ($file['size'] > $this->image_size) {
            return json(['data' => '', 'code' => 1, 'message' => '视频大小不能超过' . ($this->image_size / 1024 / 1024) . 'M']);
        }
        $name = $file['name'];
        $format = strrchr($name, '.');//截取文件后缀名如 (.jpg)
        /*判断图片格式*/
        $allow_type = ['.jpg', '.jpeg', '.gif', '.bmp', '.png'];
        if (!in_array($format, $allow_type)) {
            return json(['data' => '', 'code' => 1, 'message' => '图片格式不在允许范围内']);
        }
        // 尝试执行
        try {
            //实例化对象 将配置传入
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            //这里是有sha1加密 生成文件名 之后连接上后缀
            $fileName = 'upload/image/' . date("Ymd") . '/' . sha1(date('YmdHis', time()) . uniqid()) . $format;
            //执行阿里云上传
            $result = $ossClient->uploadFile($this->bucket, $fileName, $file['tmp_name']);
            /*组合返回数据*/
            $arr = [
                'oss_url' => $result['info']['url'],  //上传资源地址
                'relative_path' => $fileName     //数据库保存名称(相对路径)
            ];
        } catch (OssException $e) {
            return json(['data' => $e->getMessage(), 'code' => 1, 'message' => '上传失败！']);
        }
        //将结果返回
        return json(['data' => array('file' => $arr['oss_url']), 'code' => 0, 'message' => '成功上传到oss']);
    }

    /**
     * 上传图片base64
     */
    public function uploadImageBase64()
    {
        // 判断提交方式及图片类型
        if (!request()->has('base64', 'post')) {
            return json(['data' => '', 'code' => 1, 'message' => '请求方式错误，或图片非base64格式类型']);
        }
        $data = $_POST['base64'];
        $result = $this->new_base64_upload($data);
        if ($result['code'] !== 200) {
            return json(['data' => '', 'code' => 1, 'message' => $result['msg']]);
        }
        $fileResult = &$result['data'];
        $filePath = $fileResult['path'] . $fileResult['name'];
        $ossFileName = implode('/', ['upload/image', date('Ymd'), $fileResult['name']]);
        try {
            //实例化对象 将配置传入
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $result = $ossClient->uploadFile($this->bucket, $ossFileName, $filePath);
            $arr = [
                'oss_url' => $result['info']['url'],  //上传资源地址
                'relative_path' => $ossFileName     //数据库保存名称(相对路径)
            ];
        } catch (OssException $e) {
            return json(['data' => $e->getMessage(), 'code' => 1, 'message' => '上传失败']);
        }
        unlink($filePath);
        return json(['data' => array('file' => $arr['oss_url']), 'code' => 0, 'message' => '成功上传到oss']);
    }

    /**
     * 将Base64数据转换成二进制并存储到指定路径
     */
    protected function new_base64_upload($base64, $image_path = 'upload/posts/')
    {
        $data = explode(',', $base64);
        trace($data, 'api');
        unset($base64);
        if (count($data) !== 2) {
            return ['code' => 400, 'msg' => '文件格式错误'];
        }
        if (!preg_match('/^(data:\s*image\/(\w+);base64)/', $data[0], $result)) {
            return ['code' => 400, 'msg' => '文件格式错误'];
        }
        $type = $result[2];
        if (!in_array($type, array('jpeg', 'jpg', 'gif', 'bmp', 'png'))) {
            return ['code' => 400, 'msg' => '文件格式不在允许范围内'];
        }
        $image_name = md5(uniqid()) . '.' . $result[2];
        $image_file = $image_path . $image_name;
        //服务器文件存储路径
        try {
            if (file_put_contents($image_file, base64_decode($data[1]))) {
                return ['code' => 200, 'msg' => '成功', 'data' => ['name' => $image_name, 'path' => $image_path]];
            } else {
                return ['code' => 400, 'msg' => '文件保存失败'];
            }
        } catch (\Exception $e) {
            $msg = $e->getMessage();
            return ['code' => 400, 'msg' => $msg];
        }
    }


}
